package com.wetool.service.invoicing;

import java.util.ArrayList;
import java.util.List;
import javax.transaction.Transactional;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import com.wetool.entity.invoicing.InventoryRecord;
import com.wetool.entity.invoicing.InventoryRecordCommodity;
import com.wetool.entity.invoicing.InvoicingCommodity;
import com.wetool.entity.invoicing.Supplier;
import com.wetool.exception.CommodityNotFindException;
import com.wetool.exception.invoicing.AddSupplierException;
import com.wetool.exception.invoicing.ShopNotLoginException;
import com.wetool.exception.invoicing.SpplitNotFindException;
import com.wetool.exception.invoicing.StorageNotFindException;
import com.wetool.jpa.invoicing.SupplierRepo;
import com.wetool.model.enums.OutOfStorage;
import com.wetool.model.invoicing.SearchParam;
import com.wetool.model.invoicing.SupplierAdd;
import com.wetool.model.invoicing.SupplierModify;
import com.wetool.service.InvoicingCommodityService;
import com.wetool.spec.invoicing.SupplierSpec;
import com.wetool.utils.BeanUtils;

/**
 * 描述：供应商service
 * 供应商信息业务处理
 * @author lixin
 */
@Component
public class SupplierService {
	private static final Logger logger = LogManager.getLogger(SupplierService.class);

	@Autowired
	private SupplierRepo supplierRepo;
	
	@Autowired
	private InventoryService inventoryService;
	
	@Autowired
	private InvoicingCommodityService commodityService;

	/**
	 * 查询供应商列表
	 * @param searchParam 查询参数对象
	 * @param Pageable 分页对象
	 * @return Page<Supplier> 分页对象集合
	 * @throws CommodityNotFindException 
	 * @throws ShopNotLoginException 
	 */
	public Page<Supplier> findAll(SearchParam searchParam, Pageable p) throws CommodityNotFindException, ShopNotLoginException {
		if (searchParam.getShopId() == null) {
			logger.debug("查询供应商列表 店铺ID为空");
			throw new ShopNotLoginException("查询供应商列表 店铺ID为空");
		}
		SupplierSpec spec = new SupplierSpec(searchParam);//条件生成查询规则
		Page<Supplier> page = supplierRepo.findAll(spec, p);
		List<Supplier> suppliers = page.getContent();
		for (Supplier supplier : suppliers) {
			Long count = countBySupplier(supplier.getId(),supplier.getShopId());
			supplier.setCount(count);
		}
		return page;
	}
	
	/**
	 * 根据ID查询供应商
	 * @param id 供应商ID
	 * @return Supplier 供应商信息
	 */
	public SupplierModify findOne(Long id) {
		SupplierModify supplierModify = new SupplierModify();
		Supplier supplier = supplierRepo.findOne(id);//通过ID查询对应的供应商
		BeanUtils.copyProperties(supplier, supplierModify);//属性值复制到entity模型
		return supplierModify;
	}
	
	/**
	 * 供应商下商品数量
	 * @param searchParam
	 * @return
	 * @throws CommodityNotFindException
	 */
	public Long countBySupplier(Long supplierId,Long shopId) throws CommodityNotFindException {
		return inventoryService.countBySupplierIdAndShopId(supplierId, shopId);
	}
	
	/**
	 * 供应商商品查询
	 * @param searchParam
	 * @return List<Commodity>
	 * @throws CommodityNotFindException 
	 * @throws StorageNotFindException 
	 */
	public List<InvoicingCommodity> findBySupplierToCommodity(SearchParam searchParam,Pageable p) 
			throws CommodityNotFindException, ShopNotLoginException, StorageNotFindException {
		if (searchParam.getShopId() == null) {
			logger.debug("供应商商品查询 店铺ID为空");
			throw new ShopNotLoginException("供应商商品查询 店铺ID为空");
		}
		List<InvoicingCommodity> commoditys = null;
		searchParam.setOutOfStorage(OutOfStorage.STORAGE);
		Page<InventoryRecord> page = inventoryService.findAll(searchParam, p);//条件查询
		List<InventoryRecord> storages = page.getContent();//从Page对象获取集合
		List<Long> ids = getCommodityId(storages);
		if (ids != null && ids.size() > 0) {
			commoditys = commodityService.findBySupplier(searchParam,ids);
		}else {
			commoditys = new ArrayList<>();
		}
		return commoditys;
	}

	/**
	 * 添加供应商
	 * @param supplierAdd 添加供应商参数
	 * @return Supplier 供应商对象
	 * @throws AddSupplierException 添加供应商异常
	 * @throws ShopNotLoginException 
	 */
	@Transactional
	public Supplier save(SupplierAdd supplierAdd) throws AddSupplierException, ShopNotLoginException {
		if (supplierAdd.getShopId() == null) {
			logger.debug("添加供应商 店铺ID为空");
			throw new ShopNotLoginException("添加供应商 店铺ID为空");
		}
		Supplier supplier = new Supplier();
		BeanUtils.copyProperties(supplierAdd, supplier);//属性值复制到展示对象
		supplier.setIsDeleted(false);
		Supplier sup = supplierRepo.save(supplier);
		if (sup == null) {
			logger.debug("添加供应商 添加供应商失败");
			throw new AddSupplierException();
		}
		return sup;
	}
	

	/**
	 * 根据店铺id查询供应商
	 * @param shopId
	 * @return
	 * @throws ShopNotLoginException 
	 */
	public List<Supplier> findByShopId(Long shopId) throws ShopNotLoginException {
		if (shopId == null) {
			logger.debug("供应商商品查询 店铺ID为空");
			throw new ShopNotLoginException("供应商商品查询 店铺ID为空");
		}
		return supplierRepo.findByShopIdAndIsDeleted(shopId,false);
	}
	
	/**
	 * 修改供应商数据
	 * @param supplierModify 
	 * @return Supplier
	 * @throws ShopNotLoginException 
	 */
	@Transactional
	public Supplier updateSupplier(SupplierModify supplierModify) throws ShopNotLoginException {
		if (supplierModify.getShopId() == null) {
			logger.debug("修改供应商数据 店铺ID为空");
			throw new ShopNotLoginException();
		}
		Supplier supplier = new Supplier();
		BeanUtils.copyProperties(supplierModify, supplier);//属性值复制到展示对象
		supplier.setIsDeleted(false);
		return this.supplierRepo.saveAndFlush(supplier);
	}

	/**
	 * 删除供应商 （逻辑删除）
	 * @param id 删除供应商ID
	 * @throws SpplitNotFindException 
	 */
	@Transactional
	public void delete(Long id) throws SpplitNotFindException {
		Supplier sup = supplierRepo.findOne(id);//获取需删除供应商对象
		if(sup == null || sup.getIsDeleted() == true){
			logger.debug("删除供应商 供应商不存在或被逻辑删除 . 参数：供应商ID【{}】",id);
			throw new SpplitNotFindException();//为空或已经逻辑删除抛出异常
		}
		sup.setIsDeleted(true);
		supplierRepo.save(sup);
	}

	/**
	 * 通过供应商ID查询库存商品ID集合
	 * @param storages 入库单集合
	 * @return
	 */
	private List<Long> getCommodityId(List<InventoryRecord> storages){
		List<InventoryRecordCommodity> scs = storages.stream() //使用stream重构list
				.filter(item -> item.getCommoditys() != null)//过滤器过滤属性不为空值
				.collect(
				() -> new ArrayList<InventoryRecordCommodity>(),
				(list,item) -> list.addAll(item.getCommoditys()),
				(list1, list2) -> list1.addAll(list2)
				);//通过stream生成List<StorageCommodity>获取入库商品信息
		 List<Long> ids = scs.stream() //使用stream重构list
				 .filter(item -> item.getCommodityId() != null)//过滤器过滤商品ID不为空值
				 .collect(
				() -> new ArrayList<Long>(),
				(list,item) -> list.add(item.getCommodityId()),
				(list1,list2) -> list1.addAll(list2)
				);//通过stream生成List<Long> 获取商品ID集合
		 return ids;
	}

	/**
	 * 通过Id 查询名称
	 */
	public String getName(Long id ){
		return supplierRepo.getByIdToName(id);
	}
}
